/* 
 * This program is free software; you can redistribute it and/or modify 
 * it under the terms of the GNU General Public License as published by 
 * the Free Software Foundation; either version 3 of the License, or 
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful, but 
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 
 * for more details.
 * 
 * You should have received a copy of the GNU General Public License along 
 * with this program; if not, write to the Free Software Foundation, Inc., 
 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */

#include <algorithm>
#include <QDateTime>
#include <QVariant>
#include <QtPlugin>
#include "hanabiraagent.h"
#include "log.h"
#include "components/chan.h"
#include "network/cookiestorage.h"
#include "tasks/taskboardrequest.h"
#include "tasks/taskthreadrequest.h"

namespace Wishmaster
{
	HanabiraAgent::HanabiraAgent(const QString& host) : DefaultAgent(host),
		m_host(host)
	{
	}

	HanabiraAgent::~HanabiraAgent()
	{
	}

	void HanabiraAgent::makePost(const PostDescriptor& post, const QString& captcha)
	{
		QDateTime t = QDateTime::currentDateTime();
		QString script = post.board + "post/new.xhtml";
		if(post.attachments.count() > 0)
			script += QString("?X-Progress-ID=%1%2").arg(t.toTime_t()).arg("000000");

		HttpRequestPtr request = connector()->makeHttpRequest(m_host, script, "POST");
		request->addPostField("thread_id", post.parent_thread.threadStringId());
		request->addPostField("task", "post");
		request->addPostField("scroll_to", post.parent_thread.threadStringId());
		request->addPostField("name", post.name);
		if(post.sage)
			request->addPostField("sage", "checked");
		request->addPostField("subject", post.topic);
		request->addPostField("message", post.text);
		request->addPostField("captcha", captcha);
		request->addPostField("password", post.password);

		CookieStorage* storage = connector()->cookieStorage();
		if(storage->cookie(m_host, "settings").isEmpty())
		{
			storage->setCookie(m_host, "settings", QString("%1%2").arg(t.toTime_t()).arg("000"));
		}

		if(post.attachments.count() > 0)
		{
			request->addPostField("post_files_count", QString::number(post.attachments.count()));
			for(int i = 0; i < post.attachments.count(); i++)
			{
				addAttachments(request, post.attachments.at(i), QString("file_%1").arg(i + 1));
				request->addPostField(QString("file_%1_rating").arg(i + 1), post.attachments.at(i).rating);
			}
		}
		else
		{
			request->addPostField("post_files_count", QString::number(post.attachments.count()));
			addAttachments(request, AttachmentDescriptor(), "file_1");
				request->addPostField("file_1_rating", "SFW");
		}

		request->addPostField("goto", "board");
		request->setProperty("board", post.board);
		request->setProperty("thread_id", (uint)post.parent_thread.threadNumericId());

		QString referer = QString("http://%1%2res/%3.xhtml").arg(m_host).arg(post.board).arg(post.parent_thread.threadNumericId());
		request->setReferer(referer);

		connector()->connectRequest(this, SLOT(resultPost(RequestPtr, const QByteArray&)), 0, request);
		connector()->queue(request);
	}

	void HanabiraAgent::createThread(const PostDescriptor& post, const QString& captcha)
	{
		QDateTime t = QDateTime::currentDateTime();
		QString script = post.board + "post/new.xhtml";
		if(post.attachments.count() > 0)
			script += QString("?X-Progress-ID=%1%2").arg(t.toTime_t()).arg("000000");

		HttpRequestPtr request = connector()->makeHttpRequest(m_host, script, "POST");
		request->addPostField("thread_id", "0");
		request->addPostField("task", "post");
		request->addPostField("name", post.name);
		if(post.sage)
			request->addPostField("sage", "checked");
		request->addPostField("subject", post.topic);
		request->addPostField("message", post.text);
		request->addPostField("captcha", captcha);
		request->addPostField("password", post.password);

		CookieStorage* storage = connector()->cookieStorage();
		if(storage->cookie(m_host, "settings").isEmpty())
		{
			storage->setCookie(m_host, "settings", QString("%1%2").arg(t.toTime_t()).arg("000"));
		}
		if(post.attachments.count() > 0)
		{
			request->addPostField("post_files_count", QString::number(post.attachments.count()));
			for(int i = 0; i < post.attachments.count(); i++)
			{
				addAttachments(request, post.attachments.at(i), QString("file_%1").arg(i + 1));
				request->addPostField(QString("file_%1_rating").arg(i + 1), post.attachments.at(i).rating);
			}
		}
		else
		{
			request->addPostField("post_files_count", QString::number(post.attachments.count()));
			addAttachments(request, AttachmentDescriptor(), "file_1");
				request->addPostField("file_1_rating", "SFW");
		}

		request->addPostField("goto", "board");

		request->setProperty("board", post.board);
		request->setProperty("thread_id", 0);

		QString referer = QString("http://%1%2").arg(m_host).arg(post.board);
		request->setReferer(referer);

		connector()->connectRequest(this, SLOT(resultPost(RequestPtr, const QByteArray&)), 0, request);
		connector()->queue(request);
	}

	void HanabiraAgent::requestThread(const ThreadId& threadId, const PostId& lastPostId)
	{
		QString reqlink;
		if(lastPostId.isValid() && (lastPostId.postId() > 0))
			reqlink = QString("%1res/%2.xml?last_post=%3").arg(threadId.boardId()).arg(threadId.threadNumericId()).arg(lastPostId.postId());
		else
			reqlink = QString("%1res/%2.xml").arg(threadId.boardId()).arg(threadId.threadNumericId());

		QUrl url("http://" + makeFullHostname(threadId.boardId()) + reqlink);
		TaskThreadRequest* task = new TaskThreadRequest(threadId, url, tr("Requesting thread: %1").arg(threadId.threadNumericId()), connector());
		connect(task, SIGNAL(result(TaskThreadRequest*, QByteArray, QString)), this, SLOT(slot_thread(TaskThreadRequest*, QByteArray, QString)));
		TaskPtr taskptr = TaskPtr(task);
		taskhub()->queueTask(taskptr);
	}

	void HanabiraAgent::requestBoardIndex(const QString& boardId)
	{
		QUrl url("http://" + makeFullHostname(boardId) + boardId + "index.xml");
		TaskBoardRequest* task = new TaskBoardRequest(m_host, boardId, url, tr("Requesting board index: %1 (%2)").arg(boardId).arg(m_host), connector());
		connect(task, SIGNAL(result(TaskBoardRequest*, QByteArray, QString)), this, SLOT(slot_board(TaskBoardRequest*, QByteArray, QString)));
		TaskPtr taskptr = TaskPtr(task);
		taskhub()->queueTask(taskptr);
	}

	void HanabiraAgent::deleteThread(const ThreadId& threadId, const QString& password)
	{
	}

	void HanabiraAgent::deletePost(const PostId& postId, const QString& password)
	{
	}

	void HanabiraAgent::resultPost(RequestPtr r, const QByteArray& data)
	{
		QString regexp = QString::fromUtf8("<center><h2>([^<>]*)</h2></center>");
		QRegExp rx(regexp);
		if(rx.indexIn(QString::fromUtf8(data)) != -1)
		{
			log(llDebug, "Error: %s", qPrintable(rx.cap(1)));
			emit postingError(rx.cap(1));
			return;
		}
		emit postingDone(ThreadId(m_host, r->property("board").toString(), r->property("thread_id").toUInt()));
	}

	QStringList HanabiraAgent::contentRatings()
	{
		QStringList list;
		list.append("SFW");
		list.append("R-15");
		list.append("R-18");
		list.append("R-18G");
		return list;
	}

	ChanAgent* HanabiraAgent::clone(const QString& host)
	{
		return new HanabiraAgent(host);
	}

	QString HanabiraAgent::id()
	{
		return "hanabira";
	}
}

Q_EXPORT_PLUGIN2(hanabiraagent, Wishmaster::HanabiraAgent)
